package com.lanlian.cayman;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;

import com.lanlian.cayman.fragment.MarketFragment;
import com.lanlian.cayman.utils.NumberManager;
import com.lanlian.cayman.utils.VolleyRequestUtils;
import com.lanlian.commonlib.bean.BaseResponse;
import com.lanlian.commonlib.bean.PositionDetailsInfo;
import com.lanlian.commonlib.bean.ReqPositionDetails;
import com.lanlian.commonlib.bean.ReqUnitAsset;
import com.lanlian.commonlib.bean.RespPositionDetails;
import com.lanlian.commonlib.bean.RespUnitAsset;
import com.lanlian.commonlib.bean.UnitAssetInfo;
import com.lanlian.commonlib.dao.DBManager;
import com.lanlian.commonlib.data.GoodsBean;
import com.lanlian.commonlib.event.EventCode;
import com.lanlian.commonlib.event.EventMessage;
import com.lanlian.commonlib.network.INetWorkCallback;
import com.lanlian.commonlib.util.EventBusUtils;
import com.lanlian.utillib.NumberUtils;
import com.lanlian.utillib.ToastUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.math.BigDecimal;
import java.util.ArrayList;

import static java.math.BigDecimal.ROUND_HALF_DOWN;
import static java.math.BigDecimal.ROUND_HALF_UP;

/**
 * <pre>
 *     author : huxiaobo
 *     e-mail : huxiaobo@xlanlian.com
 *     date   : 2018/9/6 16:00
 *     desc   : todo
 *     version: 1.0
 * </pre>
 */
public class CalculationService extends Service {

    private final String TAG = "CalculationService";
    private UnitAssetInfo mUnitAssetInfo;
    private ArrayList<PositionDetailsInfo> mList = new ArrayList<>();

    @Override
    public void onCreate() {
        super.onCreate();
        EventBusUtils.register(this);
        //适配8.0service
        NotificationManager notificationManager = (NotificationManager) LLApplication.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel mChannel = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            mChannel = new NotificationChannel(TAG, "Lion Brokers", NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(mChannel);
            Notification notification = new Notification.Builder(getApplicationContext(), TAG).build();
            startForeground(1, notification);
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (DBManager.getInstance().isLogined()) {
            getUnitAsset();
            getPositionDetails();
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void getUnitAsset() {
        VolleyRequestUtils.getInstance().getUnitAsset(this.toString(), new ReqUnitAsset(), new INetWorkCallback() {
            @Override
            public void onSuccess(Object response) {
                RespUnitAsset respUnitAsset = (RespUnitAsset) response;
                mUnitAssetInfo = respUnitAsset.getUnitAsset();
                LLApplication.mUnitAssetInfo = mUnitAssetInfo;
                dynamicCalculation(null);
                calculation2();
            }

            @Override
            public void onFail(BaseResponse baseResponse) {
                ToastUtils.show(LLApplication.getInstance(), baseResponse.getMsg());
            }
        });
    }

    /**
     * 获取持仓信息
     */
    private void getPositionDetails() {
        VolleyRequestUtils.getInstance().getPositionDetails(this.toString(), new ReqPositionDetails(),
                new INetWorkCallback() {
                    @Override
                    public void onSuccess(Object response) {
                        RespPositionDetails respPositionDetails = (RespPositionDetails) response;
                        mList = respPositionDetails.getDataList();
                        LLApplication.setPositionList(mList);
                        calculation();
                    }

                    @Override
                    public void onFail(BaseResponse baseResponse) {
                        ToastUtils.show(LLApplication.getInstance(), baseResponse.getMsg());
                    }
                });
    }

    private void calculation() {
        if (mList != null) {
            double deposit = 0;
            double deposit2 = 0;
            double overnightDeposit = 0;
            for (PositionDetailsInfo positionDetailsInfo : mList) {
                if (MarketFragment.getRespMarket() == null) {
                    continue;
                }
                overnightDeposit += positionDetailsInfo.getEnOvernightDeposit();
                deposit2 += positionDetailsInfo.getEnFuturesDeposit();
                if (positionDetailsInfo.getEnOvernightDeposit() == 0) {
                    deposit += positionDetailsInfo.getEnFuturesDeposit();
                }
                GoodsBean goodsBean = MarketFragment.getRespMarket().getGoods(positionDetailsInfo.getVcContractCode());
                if (goodsBean == null) {
                    continue;
                }
                int count = NumberManager.getNumberDecimalDigits(goodsBean.minChange);
                double currentPrice = NumberUtils.round(positionDetailsInfo.getPrice(), count, ROUND_HALF_UP);
                positionDetailsInfo.setCurrentPrice(String.valueOf(currentPrice));
                int flag = "1".equals(positionDetailsInfo.getcPositionFlag()) ? 1 : -1;
                double averagePrice = positionDetailsInfo.getEnTotalValue() / Double.parseDouble(goodsBean.contractMultiplier)
                        / positionDetailsInfo.getlCurrentAmount();
                double basePnl = NumberUtils.sub(currentPrice, averagePrice)
                        / Double.parseDouble(goodsBean.minChange) * Double.parseDouble(goodsBean.priceUnitBase) * flag
                        * positionDetailsInfo.getlCurrentAmount();
                double pnl = NumberUtils.sub(currentPrice, averagePrice)
                        / Double.parseDouble(goodsBean.minChange) * Double.parseDouble(goodsBean.priceUnit) * flag
                        * positionDetailsInfo.getlCurrentAmount();
                positionDetailsInfo.setJj(averagePrice);
                positionDetailsInfo.setAveragePrice(NumberUtils.roundStr(averagePrice, count + 1, BigDecimal.ROUND_HALF_UP));
                positionDetailsInfo.setProfitLoss(NumberUtils.round(pnl, 2, ROUND_HALF_DOWN));
                positionDetailsInfo.setBaseProfitLoss(NumberUtils.round(basePnl, 2, ROUND_HALF_DOWN));
            }
            LLApplication.deposit = deposit;
            LLApplication.deposit2 = deposit2;
            LLApplication.overnightDeposit = overnightDeposit;
            dynamicCalculation(null);
        }
    }

    private void calculation2() {
        if (mUnitAssetInfo != null) {
            LLApplication.actualPnl = mUnitAssetInfo.getTodayYk();
            LLApplication.beginCash = mUnitAssetInfo.getEnBeginCash();
            LLApplication.intoCash = mUnitAssetInfo.getEnIntoCash();
            LLApplication.withdrawCash = mUnitAssetInfo.getEnWithdrawCash();
            LLApplication.drawAble = mUnitAssetInfo.getDrawAble();
        }
    }

    private void dynamicCalculation(HqMsg.YsHqInfo ysHqInfo) {
        if (ysHqInfo == null) {
            if (mList != null) {
                double positionPnl = calculationTotalPnl();
                LLApplication.positionPnl = positionPnl;
                if (mUnitAssetInfo != null) {
                    LLApplication.availableFunds = mUnitAssetInfo.getEnCurrentCash() - mUnitAssetInfo.getEnFrozenCapital() -
                            mUnitAssetInfo.getEnTempFrozenCapital() + positionPnl;
                    LLApplication.dynamicPnl = mUnitAssetInfo.getEnCurrentCash() + LLApplication.getDeposit2()
                            + positionPnl - mUnitAssetInfo.getWithdrawFrozen();
                }
            }
        } else {
            if (mList != null) {
                double positionPnl = calculationPnl(ysHqInfo);
                LLApplication.positionPnl = positionPnl;
                if (mUnitAssetInfo != null) {
                    LLApplication.availableFunds = mUnitAssetInfo.getEnCurrentCash() - mUnitAssetInfo.getEnFrozenCapital() -
                            mUnitAssetInfo.getEnTempFrozenCapital() + positionPnl;
                    LLApplication.dynamicPnl = mUnitAssetInfo.getEnCurrentCash() + LLApplication.getDeposit2()
                            + positionPnl - mUnitAssetInfo.getWithdrawFrozen();
                }
            }
        }
    }

    /**
     * 计算盈亏
     */
    private double calculationPnl(HqMsg.YsHqInfo ysHqInfo) {
        for (PositionDetailsInfo positionDetailsInfo : mList) {
            if (positionDetailsInfo.getVcContractCode().equals(ysHqInfo.getCommodityNo() + ysHqInfo.getContractNo1())) {
                if (MarketFragment.getRespMarket() == null) {
                    return 0;
                }
                GoodsBean goodsBean = MarketFragment.getRespMarket().getGoods(positionDetailsInfo.getVcContractCode());
                if (goodsBean != null) {
                    int count = NumberManager.getNumberDecimalDigits(goodsBean.minChange);
                    double currentPrice = NumberUtils.round(ysHqInfo.getQLastPrice(), count, ROUND_HALF_UP);
                    positionDetailsInfo.setCurrentPrice(String.valueOf(currentPrice));
                    int flag = "1".equals(positionDetailsInfo.getcPositionFlag()) ? 1 : -1;
                    double averagePrice = positionDetailsInfo.getEnTotalValue() / Double.parseDouble(goodsBean.contractMultiplier)
                            / positionDetailsInfo.getlCurrentAmount();
                    double basePnl = NumberUtils.sub(currentPrice, averagePrice)
                            / Double.parseDouble(goodsBean.minChange) * Double.parseDouble(goodsBean.priceUnitBase) * flag
                            * positionDetailsInfo.getlCurrentAmount();
                    double pnl = NumberUtils.sub(currentPrice, averagePrice)
                            / Double.parseDouble(goodsBean.minChange) * Double.parseDouble(goodsBean.priceUnit) * flag
                            * positionDetailsInfo.getlCurrentAmount();
                    positionDetailsInfo.setJj(averagePrice);
                    positionDetailsInfo.setAveragePrice(NumberUtils.roundStr(averagePrice, count + 1, BigDecimal.ROUND_HALF_UP));
                    positionDetailsInfo.setProfitLoss(NumberUtils.round(pnl, 2, ROUND_HALF_DOWN));
                    positionDetailsInfo.setBaseProfitLoss(NumberUtils.round(basePnl, 2, ROUND_HALF_DOWN));
                }
                return calculationTotalPnl();
            }
        }
        return calculationTotalPnl();
    }

    private double calculationTotalPnl() {
        double totalPnl = 0;
        for (PositionDetailsInfo positionDetailsInfo : mList) {
            totalPnl += positionDetailsInfo.getBaseProfitLoss();
        }
        return totalPnl;
    }

    @Override
    public void onDestroy() {
        EventBusUtils.unregister(this);
        super.onDestroy();
    }

    /**
     * 接收到分发的事件
     *
     * @param event 事件
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onReceiveEvent(EventMessage event) {
        switch (event.getCode()) {
            case EventCode.EVENT_MARKET:
                HqMsg.YsHqInfo ysHqInfo = (HqMsg.YsHqInfo) event.getData();
                if (ysHqInfo != null) {
                    dynamicCalculation(ysHqInfo);
                }
                break;
            case EventCode.EVENT_FUNDS_REFRESH:
                if (DBManager.getInstance().isLogined()) {
                    getUnitAsset();
                    getPositionDetails();
                }
                break;
            default:
                break;
        }
    }

}
